package cn.edu.ncut.cs.springboot.petmanagementsystem.service.Impl;

import cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.PetHealthRecordMapper;
import cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.PetMapper;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.Pet;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.PetHealthRecord;
import cn.edu.ncut.cs.springboot.petmanagementsystem.service.PetHealthService;
import cn.edu.ncut.cs.springboot.petmanagementsystem.vo.PetHealthRecordVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.chrono.ChronoLocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PetHealthServiceImpl implements PetHealthService {

    @Autowired
    private PetHealthRecordMapper healthRecordMapper;

    @Autowired
    private PetMapper petMapper;

    @Override
    @Transactional(rollbackOn = Exception.class)
    public boolean createHealthRecord(PetHealthRecord record) {
        if (record == null || record.getPetId() == null) {
            throw new IllegalArgumentException("宠物ID不能为空");
        }

        record.setCreateTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());

        int result = healthRecordMapper.insert(record);
        return result > 0;
    }

    @Override
    public IPage<PetHealthRecord> getHealthRecordsByPetId(Integer pageNum, Integer pageSize, Long petId) {
        Page<PetHealthRecord> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<PetHealthRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PetHealthRecord::getPetId, petId);
        wrapper.orderByDesc(PetHealthRecord::getCheckDate);
        return healthRecordMapper.selectPage(page, wrapper);
    }

    @Override
    public IPage<PetHealthRecordVO> getHealthRecords(Integer pageNum, Integer pageSize, Long petId, String petName, Integer status) {
        Page<PetHealthRecordVO> page = new Page<>(pageNum, pageSize);
        return healthRecordMapper.selectHealthRecordPage(page, petId, petName, status);
    }

    @Override
    public PetHealthRecord getHealthRecordById(Long id) {
        if (id == null) {
            return null;
        }
        return healthRecordMapper.selectById(id);
    }

    @Override
    public PetHealthRecordVO getHealthRecordDetailById(Long id) {
        if (id == null) {
            return null;
        }
        return healthRecordMapper.selectHealthRecordById(id);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public boolean updateHealthRecord(PetHealthRecord record) {
        if (record == null || record.getId() == null) {
            return false;
        }

        record.setUpdateTime(LocalDateTime.now());
        int result = healthRecordMapper.updateById(record);
        return result > 0;
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public boolean deleteHealthRecord(Long id) {
        if (id == null) {
            return false;
        }
        int result = healthRecordMapper.deleteById(id);
        return result > 0;
    }

    @Override
    public Map<String, Object> getHealthStatistics(Long petId) {
        Map<String, Object> statistics = new HashMap<>();
        
        if (petId == null) {
            return statistics;
        }
        
        // 查询该宠物的所有健康记录
        LambdaQueryWrapper<PetHealthRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PetHealthRecord::getPetId, petId);
        wrapper.orderByDesc(PetHealthRecord::getCheckDate);
        List<PetHealthRecord> records = healthRecordMapper.selectList(wrapper);
        
        // 总记录数
        statistics.put("totalRecords", records.size());
        
        // 按记录类型统计
        Map<String, Long> recordTypeCount = records.stream()
            .collect(Collectors.groupingBy(
                record -> record.getRecordType() != null ? record.getRecordType() : "未分类",
                Collectors.counting()
            ));
        statistics.put("recordTypeCount", recordTypeCount);
        
        // 最近一次检查时间
        if (!records.isEmpty()) {
            statistics.put("lastCheckDate", records.get(0).getCheckDate());
        } else {
            statistics.put("lastCheckDate", null);
        }
        
        // 计算平均费用
        double avgCost = records.stream()
            .filter(r -> r.getCost() != null)
            .mapToDouble(r -> r.getCost().doubleValue())
            .average()
            .orElse(0.0);
        statistics.put("averageCost", Math.round(avgCost * 100.0) / 100.0);
        
        // 总费用
        double totalCost = records.stream()
            .filter(r -> r.getCost() != null)
            .mapToDouble(r -> r.getCost().doubleValue())
            .sum();
        statistics.put("totalCost", Math.round(totalCost * 100.0) / 100.0);
        
        // 近6个月的记录数
        LocalDate sixMonthsAgo = LocalDate.now().minusMonths(6);
        long recentRecords = records.stream()
            .filter(r -> r.getCheckDate() != null && r.getCheckDate().isAfter(sixMonthsAgo))
            .count();
        statistics.put("recentSixMonthsRecords", recentRecords);
        
        // 即将到期的复查（下次就诊日期在未来30天内）
        LocalDate now = LocalDate.now();
        LocalDate thirtyDaysLater = now.plusDays(30);
        List<Map<String, Object>> upcomingVisits = records.stream()
            .filter(r -> r.getNextCheckDate() != null 
                && r.getNextCheckDate().isAfter(now)
                && r.getNextCheckDate().isBefore(thirtyDaysLater))
            .map(r -> {
                Map<String, Object> visit = new HashMap<>();
                visit.put("id", r.getId());
                visit.put("recordType", r.getRecordType() != null ? r.getRecordType() : "未分类");
                visit.put("nextVisitDate", r.getNextCheckDate());
                visit.put("description", r.getDescription() != null ? r.getDescription() : 
                    (r.getDiagnosis() != null ? r.getDiagnosis() : ""));
                return visit;
            })
            .collect(Collectors.toList());
        statistics.put("upcomingVisits", upcomingVisits);
        
        return statistics;
    }

    @Override
    public List<Map<String, Object>> getHealthReminders(Long userId) {
        List<Map<String, Object>> reminders = new ArrayList<>();
        
        if (userId == null) {
            return reminders;
        }
        
        // 查询该用户的所有宠物
        LambdaQueryWrapper<Pet> petWrapper = new LambdaQueryWrapper<>();
        petWrapper.eq(Pet::getOwnerId, userId);
        List<Pet> pets = petMapper.selectList(petWrapper);
        
        if (pets.isEmpty()) {
            return reminders;
        }
        
        LocalDate now = LocalDate.now();
        LocalDate thirtyDaysLater = now.plusDays(30);
        
        for (Pet pet : pets) {
            // 查询该宠物的健康记录
            LambdaQueryWrapper<PetHealthRecord> recordWrapper = new LambdaQueryWrapper<>();
            recordWrapper.eq(PetHealthRecord::getPetId, pet.getId());
            recordWrapper.orderByDesc(PetHealthRecord::getCheckDate);
            List<PetHealthRecord> records = healthRecordMapper.selectList(recordWrapper);
            
            // 检查即将到期的复查
            for (PetHealthRecord record : records) {
                if (record.getNextCheckDate() != null 
                    && record.getNextCheckDate().isAfter(now)
                    && record.getNextCheckDate().isBefore(thirtyDaysLater)) {
                    
                    Map<String, Object> reminder = new HashMap<>();
                    reminder.put("type", "复查提醒");
                    reminder.put("petId", pet.getId());
                    reminder.put("petName", pet.getPetName());
                    reminder.put("recordId", record.getId());
                    reminder.put("recordType", record.getRecordType() != null ? record.getRecordType() : "未分类");
                    reminder.put("nextVisitDate", record.getNextCheckDate());
                    reminder.put("hospital", record.getHospital() != null ? record.getHospital() : "");
                    reminder.put("veterinarian", record.getVeterinarian() != null ? record.getVeterinarian() : "");
                    
                    long daysUntil = ChronoUnit.DAYS.between(now, record.getNextCheckDate());
                    reminder.put("daysUntil", daysUntil);
                    String recordTypeStr = record.getRecordType() != null ? record.getRecordType() : "体检";
                    reminder.put("message", pet.getPetName() + " 需要在 " + daysUntil + " 天后进行复查（" + recordTypeStr + "）");
                    reminder.put("priority", daysUntil <= 7 ? "high" : "normal");
                    
                    reminders.add(reminder);
                }
            }
            
            // 检查长时间未体检的宠物（超过6个月）
            if (!records.isEmpty()) {
                PetHealthRecord lastRecord = records.get(0);
                LocalDate sixMonthsAgo = now.minusMonths(6);
                
                if (lastRecord.getCheckDate().isBefore(sixMonthsAgo)) {
                    Map<String, Object> reminder = new HashMap<>();
                    reminder.put("type", "体检提醒");
                    reminder.put("petId", pet.getId());
                    reminder.put("petName", pet.getPetName());
                    reminder.put("lastCheckDate", lastRecord.getCheckDate());
                    
                    long monthsSince = ChronoUnit.MONTHS.between(lastRecord.getCheckDate(), now);
                    reminder.put("monthsSinceLastCheck", monthsSince);
                    reminder.put("message", pet.getPetName() + " 已经 " + monthsSince + " 个月未进行健康检查，建议尽快体检");
                    reminder.put("priority", monthsSince >= 12 ? "high" : "normal");
                    
                    reminders.add(reminder);
                }
            } else {
                // 从未有过健康记录的宠物
                Map<String, Object> reminder = new HashMap<>();
                reminder.put("type", "首次体检提醒");
                reminder.put("petId", pet.getId());
                reminder.put("petName", pet.getPetName());
                reminder.put("message", pet.getPetName() + " 还没有健康检查记录，建议进行首次健康体检");
                reminder.put("priority", "normal");
                
                reminders.add(reminder);
            }
        }
        
        // 按优先级和时间排序
        reminders.sort((r1, r2) -> {
            String priority1 = (String) r1.get("priority");
            String priority2 = (String) r2.get("priority");
            
            if ("high".equals(priority1) && !"high".equals(priority2)) {
                return -1;
            } else if (!"high".equals(priority1) && "high".equals(priority2)) {
                return 1;
            }
            
            // 优先级相同时，按天数排序
            Long days1 = (Long) r1.get("daysUntil");
            Long days2 = (Long) r2.get("daysUntil");
            if (days1 != null && days2 != null) {
                return days1.compareTo(days2);
            }
            
            return 0;
        });
        
        return reminders;
    }
}
